/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BuildTrainSet.AssignTag;

import java.util.HashMap;
import java.util.Map;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

/**
 *
 * @author Pham Thanh
 */
public final class AlphaTagPro {

    private HashMap<String, Integer> aAr = new HashMap<String, Integer>();
    private HashMap<String, Integer> eAr = new HashMap<String, Integer>();
    private HashMap<String, Integer> sAr = new HashMap<String, Integer>();
    private ArrayList conAr = new ArrayList();
    public HashSet wordAr = new HashSet();
    public ArrayList<String> greekAr = new ArrayList<String>();
    private HashMap<String, String> alphaAr = new HashMap<String, String>();

    public AlphaTagPro(String inf, String ouf, String tagedf) throws ClassNotFoundException, SQLException, UnsupportedEncodingException, XMLStreamException, FileNotFoundException, IOException {

        System.out.println("package BuildTrainSet.AssignTag; class AlphaTagPro");

        setConAr();
        setWordAr();
        setGreek();
        colect(tagedf);
        setAlphaAr();
        createAlphaTagFile(inf, ouf);
    }
//    public static void main(String argv[]) throws ClassNotFoundException, SQLException, UnsupportedEncodingException, XMLStreamException, FileNotFoundException, IOException{
//        AlphaTagPro atp=new AlphaTagPro("trainset//150.xml", "trainset//150.alpha.xml", "trainset//hand//50.hand.xml");
//    }

    public void createAlphaTagFile(String inF, String ouF) throws XMLStreamException, IOException {
        long startTime = System.currentTimeMillis();

        FileInputStream fis = new FileInputStream(inF);
        XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);

        System.out.println("Dang gan the alpha pro...");
        int aswd = 0;
        int expn = 0;
        int seqn = 0;
        FileOutputStream fos = new FileOutputStream(ouF);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
        XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(osw);
        xmlStreamWriter.writeStartElement("root");
        while (xmlStreamReader.hasNext()) {
            int eventCode = xmlStreamReader.next();
            switch (eventCode) {

                case XMLStreamConstants.START_ELEMENT:
                    String localName = xmlStreamReader.getLocalName();
                    if (localName.equals("record")) {
                        String RecId = xmlStreamReader.getAttributeValue(0);
                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeAttribute("RecId", RecId);
                    }
                    if (localName.equals("URL")) {
                        String url = xmlStreamReader.getElementText();

                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeCharacters(url);
                        xmlStreamWriter.writeEndElement();
                    }
                    if (localName.equals("Infomation")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }

                    if (localName.equals("W")) {

                        String atVal = xmlStreamReader.getAttributeValue(0);
                        if (atVal.equals("ALPHA")) {
                            String nsw = xmlStreamReader.getElementText();
                            String nswLower = nsw.toLowerCase();
                            if (isWord(nswLower)) {
                                xmlStreamWriter.writeCharacters(nsw + " ");
                            } else {
                                String atAlVal = detectAlphaTag(nsw);
                                xmlStreamWriter.writeStartElement(localName);
                                xmlStreamWriter.writeAttribute("NSW", atAlVal);
                                xmlStreamWriter.writeCharacters(nsw);
                                xmlStreamWriter.writeEndElement();
                                if (atAlVal.equals("ASWD")) {
                                    aswd++;
                                } else {
                                    if (atAlVal.equals("EXPN")) {
                                        expn++;
                                    } else {
                                        seqn++;
                                    }
                                }
                            }
                        } else {
                            xmlStreamWriter.writeStartElement(localName);
                            xmlStreamWriter.writeAttribute("NSW", atVal);
                            String nsw = xmlStreamReader.getElementText();
                            xmlStreamWriter.writeCharacters(nsw);
                            xmlStreamWriter.writeEndElement();
                        }

                    }

                    if (localName.equals("SPLIT")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }
                    break;


                case XMLStreamConstants.END_ELEMENT:
                    String endLocalName = xmlStreamReader.getLocalName();

                    if (endLocalName.equals("record")) {
                        xmlStreamWriter.writeEndElement();
                    }
                    if (endLocalName.equals("Infomation")) {
                        xmlStreamWriter.writeEndElement();
                    }

                    if (endLocalName.equals("SPLIT")) {
                        xmlStreamWriter.writeEndElement();
                    }

                    break;
                case XMLStreamConstants.CHARACTERS:
                    String character = xmlStreamReader.getText();
                    xmlStreamWriter.writeCharacters(character);
                    break;

                default:
                    break;
            }
        }
        xmlStreamWriter.writeEndElement();

        xmlStreamReader.close();
        xmlStreamWriter.close();
        fis.close();
        fos.close();
        System.out.println("    +aswd: " + aswd);
        System.out.println("    +expn: " + expn);
        System.out.println("    +seqn: " + seqn);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("Thoi gian gan the alpha la: " + time);

    }

    public boolean haveUperCase(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isUpperCase(nsw.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    public boolean haveLowerCase(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isLowerCase(nsw.charAt(i))) {
                return true;
            }
        }
        return false;

    }

    public boolean haveConsonant(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (conAr.contains(nsw.subSequence(i, i + 1))) {
                return true;
            }
        }
        return false;

    }

    public boolean haveVowel(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (!conAr.contains(nsw.subSequence(i, i + 1))) {
                return true;
            }
        }
        return false;

    }

    public boolean isAswd(String nsw) {
        if (haveConsonant(nsw) && haveLowerCase(nsw) && haveVowel(nsw)) {
            return true;
        }
        return false;

    }

    public boolean isExpn(String nsw) {
//       if(nsw.equals("%")||nsw.equals("Đ")||nsw.equals("VNĐ")||nsw.equals("$")){
//           return true;
//       }
        if (nsw.length() == 1) {
            if (Character.isUpperCase(nsw.charAt(0))) {
                if (nsw.equals("P") || nsw.equals("Q")) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return true;
            }
        }
        if (haveVowel(nsw)) {
            return false;
        }
//        if(haveLowerCase(nsw)){
//            return false;
//        }
        return true;
    }

    public boolean isWord(String nsw) {
        if (wordAr.contains(nsw)) {
            return true;
        }
//        if(nsw.equals("'")){
//            return true;
//        }
        return false;
    }

    public boolean isGreekNumber(String nsw) {
        if (greekAr.contains(nsw)) {
            return true;
        }
        return false;
    }

    public String detectAlphaTag(String nsw) {
        if (alphaAr.containsKey(nsw)) {
            return alphaAr.get(nsw);
        }
        if (isGreekNumber(nsw)) {
            return "Greek";
        }
        if (isAswd(nsw)) {
            return "ASWD";
        }
        if (isExpn(nsw)) {
            return "EXPN";
        }

        return "SEQN";
    }

    public void setConAr() throws UnsupportedEncodingException, FileNotFoundException, IOException {
//        conAr.add("B");
//        conAr.add("C");
//        conAr.add("D");
//        conAr.add("Đ");
//        conAr.add("G");
//        conAr.add("H");
//        conAr.add("K");
//        conAr.add("L");
//        conAr.add("M");
//        conAr.add("N");
//        conAr.add("P");
//        conAr.add("Q");
//        conAr.add("S");
//        conAr.add("T");
//        conAr.add("V");
//        conAr.add("X");
//        conAr.add("Y");
//        conAr.add("Z");        
//        conAr.add("b");
//        conAr.add("c");
//        conAr.add("d");
//        conAr.add("đ");
//        conAr.add("g");
//        conAr.add("h");
//        conAr.add("k");
//        conAr.add("l");
//        conAr.add("m");
//        conAr.add("n");
//        conAr.add("p");
//        conAr.add("q");
//        conAr.add("s");
//        conAr.add("t");
//        conAr.add("v");
//        conAr.add("x");
//        conAr.add("y");
//        conAr.add("z");       
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\Consonant.db"), "UTF8"));
        String Consonant;
        int i = 0;
        while ((Consonant = br.readLine()) != null) {
            conAr.add(Consonant);
//            i++;
        }
//        System.out.println(i);
    }

    public void setGreek() throws UnsupportedEncodingException, FileNotFoundException, IOException {
//        greekAr.add("I");
//        greekAr.add("II");
//        greekAr.add("III");
//        greekAr.add("IV");
//        greekAr.add("V");
//        greekAr.add("VI");
//        greekAr.add("VII");
//        greekAr.add("VIII");
//        greekAr.add("IX");
//        greekAr.add("X");
//        greekAr.add("XI");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\greekNumber.db"), "UTF8"));
        String greekNumber;
        int i = 0;
        while ((greekNumber = br.readLine()) != null) {
            greekAr.add(greekNumber);
//            i++;
        }
//        System.out.println(i);
    }

    public void setWordAr() throws UnsupportedEncodingException, FileNotFoundException, IOException {
        BufferedReader bra = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\amtiet.txt"), "UTF16"));
        String amtiet;

        while ((amtiet = bra.readLine()) != null) {
            wordAr.add(amtiet);
        }
    }

    public void colect(String tagedf) throws XMLStreamException, UnsupportedEncodingException, IOException {
        FileInputStream fis = new FileInputStream(tagedf);
        XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);
        while (xmlStreamReader.hasNext()) {
            int eventCode = xmlStreamReader.next();
            switch (eventCode) {

                case XMLStreamConstants.START_ELEMENT:
                    String localName = xmlStreamReader.getLocalName();
                    if (localName.equals("W")) {

                        if (localName.equals("W")) {
                            String atval = xmlStreamReader.getAttributeValue(0);
                            String nsw = xmlStreamReader.getElementText();
                            if (atval.equals("ASWD")) {
                                if (aAr.containsKey(nsw)) {
                                    int num = aAr.get(nsw);
                                    num++;
                                    aAr.put(nsw, num);
                                } else {
                                    aAr.put(nsw, 1);
                                }
                            }

                            if (atval.equals("SEQN")) {
                                if (sAr.containsKey(nsw)) {
                                    int num = sAr.get(nsw);
                                    num++;
                                    sAr.put(nsw, num);
                                } else {
                                    sAr.put(nsw, 1);
                                }
                            }

                            if (atval.equals("EXPN")) {
                                if (eAr.containsKey(nsw)) {
                                    int num = eAr.get(nsw);
                                    num++;
                                    eAr.put(nsw, num);
                                } else {
                                    eAr.put(nsw, 1);
                                }
                            }
                        }


                    }
            }
        }
    }

    public void setAlphaAr() {
        for (Map.Entry<String, Integer> entry : aAr.entrySet()) {
            String aswd = entry.getKey();
            alphaAr.put(aswd, "ASWD");

        }
        for (Map.Entry<String, Integer> entry : sAr.entrySet()) {
            String aswd = entry.getKey();
            alphaAr.put(aswd, "SEQN");
        }

        for (Map.Entry<String, Integer> entry : eAr.entrySet()) {
            String aswd = entry.getKey();
            alphaAr.put(aswd, "EXPN");
        }
        for (Map.Entry<String, String> entry : alphaAr.entrySet()) {
            String nsw = entry.getKey();
            int an = 0;
            int sn = 0;
            int en = 0;
            if (aAr.containsKey(nsw)) {
                an = aAr.get(nsw);
            }
            if (eAr.containsKey(nsw)) {
                en = eAr.get(nsw);
            }
            if (sAr.containsKey(nsw)) {
                sn = sAr.get(nsw);
            }

            String alTag = max(an, en, sn);
            alphaAr.put(nsw, alTag);
        }

//        for(Map.Entry<String, Integer> entry: eAr.entrySet()){
//            String expn=entry.getKey();
//            if(alphaAr.containsKey(expn)){
//                int an=aAr.get(expn);
//                int en=eAr.get(expn);
//                if(an>=en){
//                    alphaAr.put(expn, "ASWD");
//                }else{
//                    alphaAr.put(expn, "EXPN");
//                }
//            }else{
//                alphaAr.put(expn, "EXPN");
//            }
//        }
//        
//        for(Map.Entry<String,Integer> entry: sAr.entrySet()){
//            String seqn=entry.getKey();
//            if(alphaAr.containsKey(seqn)){
//                int en=eAr.get(seqn);
//                int sn=sAr.get(seqn);
//                if(en>=sn){
//                    alphaAr.put(seqn, "EXPN");
//                }else{
//                    alphaAr.put(seqn, "SEQN");
//                }
//            }else{
//                alphaAr.put(seqn, "EXPN");
//            }
//        }




    }

    public String max(int an, int en, int sn) {
        if (an >= en) {
            if (an >= sn) {
                return "ASWD";
            } else {
                return "SEQN";
            }
        } else {
            if (en >= sn) {
                return "EXPN";
            } else {
                return "SEQN";
            }
        }
    }
}
